<?php

namespace app\common\service;

use think\facade\Cache;

class WeAppletService extends ApiService
{

    protected $appid;
    protected $secret;
    protected $jscode2sessionUrl = 'https://api.weixin.qq.com/sns/jscode2session';
    protected $accessTokenUrl = 'https://api.weixin.qq.com/cgi-bin/token';
    protected $sendSubscribeMsgUrl = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send';
    protected $QRCodeUrl = 'https://api.weixin.qq.com/wxa/getwxacode';

    public function __construct()
    {
        $this->appid = env('WEAPPLET.APPID');
        $this->secret = env('WEAPPLET.SECRET');
    }

    /**
     * @param $weMiniCode string 微信小程序code
     * @return false|mixed
     */
    public function getSession(string $weMiniCode): mixed
    {
        $params = [
            'appid' => $this->appid,
            'secret' => $this->secret,
            'js_code' => $weMiniCode,
            'grant_type' => 'authorization_code',
        ];
        $result = HttpService::getRequest($this->jscode2sessionUrl, $params);
        if ($result) {
            $result = json_decode($result, true);
            if (isset($result['errcode'])) {
                $this->setError('微信小程序授权失败,code:' . $result['errcode']);
                return false;
            }
            return $result['openid'];
        }
        $this->setError('微信小程序请求失败');
        return false;
    }

    /**
     * @param $weMiniCode string 微信小程序code
     * @return false|mixed
     */
    public function getAppletInfo(string $weMiniCode): mixed
    {
        $openid = $this->getSession($weMiniCode);
        if (!$openid) {
            return false;
        }
        return $openid;
    }


    /**
     * 获取access_token
     * @return false|mixed
     */
    public function getAccessToken(): mixed
    {
        $key = 'wechat_access_token';
        $accessToken = Cache::get($key);
        if ($accessToken) {
            return $accessToken;
        }
        $params = [
            'appid' => $this->appid,
            'secret' => $this->secret,
            'grant_type' => 'client_credential',
        ];
        $result = HttpService::getRequest($this->accessTokenUrl, $params);
        $result = json_decode($result, true);
        if (isset($result['errcode'])) {
            $this->setError('获取微信小程序access_token失败,code:' . $result['errcode']);
            return false;
        }
        $expires_in = $result['expires_in'] - 100;
        Cache::set($key, $result['access_token'], $expires_in);
        return $result['access_token'];
    }

    /**
     * 创建二维码
     * @param $organizationId int 机构id
     * @param $qrcodeWidth int 二维码宽度
     * @param $env_version string 环境版本
     * @return false|string
     */
    public function createQRCode(int $organizationId, int $qrcodeWidth = 300, string $env_version = 'develop'): bool|string
    {
        $key = 'wechat_qrcode_' . $organizationId;
        $base64 = Cache::get($key);
        if ($base64) {
            return $base64;
        }
        $accessToken = $this->getAccessToken();
        if (!$accessToken) {
            return false;
        }
        $params = [
            'path' => '?o_id=' . $organizationId,
            'width' => $qrcodeWidth,
            'is_hyaline' => false,
            'env_version' => $env_version
        ];
        $url = $this->QRCodeUrl . '?access_token=' . $accessToken;
        $result = HttpService::postJson($url, $params);
        $jsonData = json_decode($result, true);
        if (json_last_error() === JSON_ERROR_NONE && isset($jsonData['errcode'])) {
            $this->setError('获取微信小程序二维码失败,code:' . $jsonData['errcode']);
            return false;
        }
        // return 'data:image/png;base64,' . base64_encode($result);
        $base64 = 'data:image/png;base64,' . base64_encode($result);
        Cache::set($key, $base64, 60 * 5);
        return $base64;
    }

    // 发送订阅消息
    public function sendSubscribeMessage($weMiniOpenid, $templateId, $templateData)
    {
        logSave([
            'templateData' => $templateData,
            'templateId' => $templateId,
            'student' => [
                'openid' => $weMiniOpenid,
            ],
            'msg' => '开课订阅消息开始发送'
        ], 'sendSubscribeMessage');
        $accessToken = $this->getAccessToken();
        if (!$accessToken) {
            return false;
        }
        $params = [
            'access_token' => $accessToken,
            'template_id' => $templateId,
            'touser' => $weMiniOpenid,
            'data' => $templateData,
            'miniprogram_state' => 'developer',// 跳转小程序类型：developer为开发版；trial为体验版；formal为正式版;
            'lang' => 'zh_CN'
        ];
        $url = $this->sendSubscribeMsgUrl . '?access_token=' . $accessToken;
        $result = HttpService::postJson($url, $params);
        $jsonData = json_decode($result, true);
        if (isset($jsonData['errcode']) && $jsonData['errcode'] == 0) {
            return true;
        }
        logSave([
            'templateData' => $templateData,
            'templateId' => $templateId,
            'student' => [
                'openid' => $weMiniOpenid,
            ],
            'result' => $jsonData,
            'msg' => '开课订阅消息发送结果'
        ], 'sendSubscribeMessage');
        $errCode = $jsonData['errcode'] ?? '';
        $this->setError('发送微信小程序订阅消息失败,code:' . $errCode);
        return false;

    }

}